#pragma once
#include "array/Array.hpp"
#include "util/ParamRegister.h"
#include "lang/StringFormat.hpp"

namespace yzrilyzr_array{
	ECLASS(SampleProvider, public yzrilyzr_util::ParamRegister){
	public:
	static constexpr int const LOOP_DISABLE=0;
	static constexpr int const LOOP_FORWARD=1;
	static constexpr int const LOOP_PING_PONG=2;
	u_index length=0;
	virtual inline u_sample operator[](u_index index)const=0;
	virtual yzrilyzr_lang::String toString()const override{ return "SampleProvider"; }
	};
	ECLASS(SampleArrayProvider, public SampleProvider){
	public:
	SampleArray array;
	SampleArrayProvider(){
		length=0;
	}
	SampleArrayProvider(const SampleArray & array) :array(array){
		length=array.length;
	}
	inline u_sample operator[](u_index index)const override{
		return array[index];
	}
	yzrilyzr_lang::String toString()const override{
		return yzrilyzr_lang::StringFormat::object2string("SampleProvider", array);
	}
	};

	ECLASS(DoubleArrayProvider, public SampleProvider){
	public:
	DoubleArray array;
	DoubleArrayProvider(){
		length=0;
	}
	DoubleArrayProvider(const DoubleArray & array) :array(array){
		length=array.length;
	}
	inline u_sample operator[](u_index index)const override{
		return array[index];
	}
	yzrilyzr_lang::String toString()const override{
		return yzrilyzr_lang::StringFormat::object2string("SampleProvider", array);
	}
	};

	ECLASS(FloatArrayProvider, public SampleProvider){
	public:
	FloatArray array;
	FloatArrayProvider(){
		length=0;
	}
	FloatArrayProvider(const FloatArray & array) :array(array){
		length=array.length;
	}
	inline u_sample operator[](u_index index)const override{
		return array[index];
	}
	yzrilyzr_lang::String toString()const override{
		return yzrilyzr_lang::StringFormat::object2string("SampleProvider", array);
	}
	};

	ECLASS(ShortArrayProvider, public SampleProvider){
	public:
	ShortArray array;
	ShortArrayProvider(){
		length=0;
	}
	ShortArrayProvider(const ShortArray & array) :array(array){
		length=array.length;
	}
	inline u_sample operator[](u_index index)const override{
		return array[index] / 32767.0;
	}
	yzrilyzr_lang::String toString()const override{
		return yzrilyzr_lang::StringFormat::object2string("SampleProvider", array);
	}
	};

	ECLASS(ByteArrayProvider, public SampleProvider){
	public:
	ByteArray array;
	ByteArrayProvider(){
		length=0;
	}
	ByteArrayProvider(const ByteArray & array) :array(array){
		length=array.length;
	}
	inline u_sample operator[](u_index index)const override{
		return array[index] / 127.0;
	}
	yzrilyzr_lang::String toString()const override{
		return yzrilyzr_lang::StringFormat::object2string("SampleProvider", array);
	}
	};
}